package com.tacc.tyun.common.shiro;

import com.tacc.tyun.common.jedis.RedisService;
import com.tacc.tyun.model.BaseUser;
import com.tacc.tyun.service.BaseUserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * shiro身份校验核心类
 * @author taocongcong
 * @create 2017-07-14 16:11
 */
public class MyShiroRealm extends AuthorizingRealm {

    @Autowired
    private BaseUserService baseUserService;

    @Autowired
    private RedisService redisService;

    //用户登录次数计数  redisKey 前缀
    private String SHIRO_LOGIN_COUNT = "shiro_login_count_";

    //用户登录是否被锁定    一小时 redisKey 前缀
    private String SHIRO_IS_LOCK = "shiro_is_lock_";

    /**
     * 认证信息.(身份验证) : Authentication 是用来验证用户身份
     *
     * @param authcToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
        UsernamePasswordToken token=(UsernamePasswordToken)authcToken;
        String username=token.getUsername();
        String password= String.valueOf(token.getPassword());
        //访问一次计数一次
        redisService.increment(SHIRO_LOGIN_COUNT+username, 1);

        //设置key的有效期
        if(Integer.parseInt(redisService.get(SHIRO_LOGIN_COUNT+username))>2){
            redisService.set(SHIRO_IS_LOCK+username,"LOCK",60);
            String s = redisService.get("SHIRO_LOGIN_COUNT+username");//计数器
            int times=1;
            if (StringUtils.isNotEmpty(s)){
                int time=Integer.parseInt(s);
                if (time>=3){
                    times=1+(time-3);
                }
            }
            redisService.expire(SHIRO_LOGIN_COUNT+username,60*times);//防止连续登陆
        }
        if (StringUtils.equals("LOCK",redisService.get(SHIRO_IS_LOCK+username))){
            throw new DisabledAccountException("由于密码输入错误次数大于3次，帐号已经禁止登录！");
        }

        //校验
        BaseUser record=new BaseUser();
        record.setUserid(username);
        record.setUserpassword(password);

        BaseUser user=null;
        List<BaseUser> userList = baseUserService.select(record);
        if(userList.size()!=0){
            user = userList.get(0);
        }
        if (null == user) {
            throw new AccountException("帐号或密码不正确！");
        }else{
            //登录成功
            //更新登录时间 last login time
            user.setLoginTime(new Date());
            baseUserService.updateByPrimaryKeySelective(user);
            //清空登录计数
            redisService.set(SHIRO_LOGIN_COUNT+username, "0");
        }
        Logger.getLogger(getClass()).info("身份认证成功，登录用户："+username);
        return new SimpleAuthenticationInfo(user, password, getName());
    }

    /**
     * 授权
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //BaseUserInfo baseUserInfo=(BaseUserInfo)SecurityUtils.getSubject().getSession().getAttribute(BaseConstant.SESSION_USERINFO);
        SimpleAuthorizationInfo info =  new SimpleAuthorizationInfo();
        Set<String> permissionSet = new HashSet<>();
        Set<String> roleNameSet = new HashSet<>();
        permissionSet.add("sysOss/picture");
        permissionSet.add("sysOss/listPage");
        roleNameSet.add("admin");
        info.setRoles(roleNameSet);
        info.setStringPermissions(permissionSet);
        return info;
    }


}
